package com.sunny.blog.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONObject;
import com.sunny.blog.common.entity.Response;
import com.sunny.blog.common.entity.ResponseResult;
import com.sunny.blog.common.entity.ResultCode;
import com.sunny.blog.common.entity.SysConstant;
import com.sunny.blog.pojo.CommentUserBean;
import com.sunny.blog.pojo.IpInfoBean;
import com.sunny.blog.pojo.LoginReqBean;
import com.sunny.blog.pojo.UserInfoBean;
import com.sunny.blog.service.ICacheService;
import com.sunny.blog.service.OpenApiService;
import com.sunny.blog.service.SmsSendService;
import com.sunny.blog.service.UserInfoService;
import com.sunny.blog.util.AesUtil;
import com.sunny.blog.util.CookieUtil;
import com.wf.captcha.SpecCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: UserInfoController
 * @Description: 后台用户管理
 * @Author: sunt
 * @Date: 2020/4/13 9:45
 * @Version 1.0
 **/
@RequestMapping("user")
@RestController
@Slf4j
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private SmsSendService smsSendService;
    @Autowired
    private OpenApiService openApiService;

    @PostMapping("queryAllUser")
    public ResponseResult<List<UserInfoBean>> queryAllUser() {
        try {
            List<UserInfoBean> userList = userInfoService.queryAllUser();
            return Response.makeOKRsp(userList);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp();
        }
    }


    @PostMapping("doLogin")
    public ResponseResult<String> doLogin(@RequestBody LoginReqBean loginReqBean,HttpServletRequest request,HttpServletResponse response) {
        try {
            JSONObject jsonObject = userInfoService.doLogin(loginReqBean);
            String errorMsg = jsonObject.getStr("errorMsg");
            if(StrUtil.isNotBlank(errorMsg)) {
                return Response.makeErrRsp(errorMsg);
            }
            String loginToken = jsonObject.getStr("loginToken");
            //写入Cookie
            ServletUtil.addCookie(response, SysConstant.BLOG_COOKIE,loginToken,-1); //关闭浏览器登录失效
            //登录成功通知
            String encryptKey = loginReqBean.getEncryptKey();
            String userName = AesUtil.deCode(loginReqBean.getUserName(), encryptKey);
            IpInfoBean ipInfoBean = openApiService.queryIpInfo(ServletUtil.getClientIP(request));
            String msgContent = "您的账号:" + userName + "在" + DateUtil.formatDateTime(DateUtil.date()) + "，成功登录系统，登录IP:" + ipInfoBean.getIp()
                    + "，登录地点:" + ipInfoBean.getAddr();
                    smsSendService.sendDingTextMsg(msgContent,null,true);
            return Response.makeRsp(ResultCode.SUCCESS.code,"登录成功",loginToken);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp();
        }
    }

    @GetMapping(value = "/genVerifyCode", produces = MediaType.IMAGE_PNG_VALUE)
    public void genVerifyCode(HttpServletResponse response) throws IOException {
        try {
            // 设置请求头为输出图片类型,github地址:https://gitee.com/whvse/EasyCaptcha
            response.setContentType(MediaType.IMAGE_PNG_VALUE);
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0L);
            // 三个参数分别为宽、高、位数
            SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
            String verifyCode = specCaptcha.text();
            log.info("---------->随机生成的验证码:" + verifyCode);
            String cacheCode = cacheService.getCacheInfoByCode(verifyCode);
            if(StrUtil.isNotBlank(cacheCode)) {
                log.info("缓存中检索到重复key:" + verifyCode + ",对应到缓存中的验证码:" + cacheCode);
            }else {
                log.info("-------->输出图片验证码到浏览器");
                cacheService.cacheStringData(verifyCode.toUpperCase(),verifyCode,1);
                specCaptcha.out(response.getOutputStream());
            }
        } catch (Exception e) {
            log.error("获取验证码异常:" + e.getMessage());
        }
    }

    /**
     * 获取登录信息
     * @param request
     * @return
     */
    @PostMapping("getLoginInfo")
    public ResponseResult<String> getLoginInfo(HttpServletRequest request) {
        try {
            Cookie cookie = ServletUtil.getCookie(request, SysConstant.BLOG_COOKIE.toLowerCase());
            if(ObjectUtil.isNull(cookie)) {
                return Response.makeErrRsp("请重新登录");
            }
            String loginToken = cookie.getValue();
            UserInfoBean cacheUser = (UserInfoBean) cacheService.getObjCacheByCode(loginToken);
            if(ObjectUtil.isNull(cacheUser)) {
                return Response.makeErrRsp("请重新登录");
            }
            return Response.makeOKRsp("登录状态正常");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp("获取登录信息异常:" + e.getMessage());
        }
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value = "/outLogin")
    public ResponseResult<Object> outLogin(HttpServletRequest request,HttpServletResponse response) {
        try {
            //获取token
            String cookieStr = CookieUtil.getCookieStr(request);
            boolean delCacheRes = cacheService.deleteCacheByKey(cookieStr);
            log.info("删除缓存key:" + cookieStr + "，返回结果:" + delCacheRes);
            CookieUtil.delCookie(response,cookieStr);
            return Response.makeOKRsp("注销成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp("注销异常:" + e.getMessage());
        }
    }


    /**
     * 前端评论用户登录
     * @param loginReqBean
     * @param response
     * @return
     */
    @PostMapping("userLogin")
    public ResponseResult<String> userLogin(@RequestBody CommentUserBean loginReqBean, HttpServletResponse response) {
        try {
            JSONObject jsonObject = userInfoService.userLogin(loginReqBean);
            String errorMsg = jsonObject.getStr("errorMsg");
            if(StrUtil.isNotBlank(errorMsg)) {
                return Response.makeErrRsp(errorMsg);
            }
            String loginToken = jsonObject.getStr("loginToken");
            //写入Cookie
            ServletUtil.addCookie(response, SysConstant.COMMENT_USER_COOKIE,loginToken,-1); //关闭浏览器登录失效
            return Response.makeRsp(ResultCode.SUCCESS.code,"登录成功",loginToken);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp();
        }
    }

    /**
     * 前端评论用户注册
     * @param commentUserBean
     * @return
     */
    @PostMapping("userRegister")
    public ResponseResult<String> userRegister(@RequestBody CommentUserBean commentUserBean) {
        try {
            JSONObject jsonObject = userInfoService.validRegister(commentUserBean);
            String errorMsg = jsonObject.getStr("errorMsg");
            if(StrUtil.isNotBlank(errorMsg)) {
                return Response.makeErrRsp(errorMsg);
            }
            userInfoService.insertCommentUser(commentUserBean);
            return Response.makeRsp(ResultCode.SUCCESS.code,"注册成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp();
        }
    }


    /**
     * 发送邮件短信验证码
     * @return
     */
    @PostMapping("sendMailCode")
    public ResponseResult<String> sendMailCode(@RequestBody Map<String, Object> params) {
        try {
            String toMail = params.get("toMail").toString();
            smsSendService.sendMailCode(toMail);
            return Response.makeRsp(ResultCode.SUCCESS.code,"验证码获取成功,请登录邮箱查看");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp("系统繁忙请稍后重试!");
        }
    }

    /**
     * 校验邮箱或者昵称是否存在
     * @param params
     * @return
     */
    @PostMapping("isExists")
    public ResponseResult<Boolean> isExists(@RequestBody Map<String, Object> params) {
        try {
            String userEmail = params.get("userEmail") == null ? null : params.get("userEmail").toString();
            String userNick = params.get("userNick") == null ? null : params.get("userNick").toString();
            boolean exists = userInfoService.isExists(userEmail, userNick);
            return Response.makeRsp(ResultCode.SUCCESS.code,"操作成功",exists);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp("系统繁忙请稍后重试!");
        }
    }


    /**
     * 获取评论用户登录状态
     * @param request
     * @return
     */
    @PostMapping("getCommentUser")
    public ResponseResult<String> getCommentUser(HttpServletRequest request) {
        try {
            Cookie cookie = ServletUtil.getCookie(request, SysConstant.COMMENT_USER_COOKIE.toLowerCase());
            if(ObjectUtil.isNull(cookie)) {
                return Response.makeErrRsp("未登录");
            }
            String loginToken = cookie.getValue();
            CommentUserBean cacheUser = (CommentUserBean) cacheService.getObjCacheByCode(loginToken);
            if(ObjectUtil.isNull(cacheUser)) {
                return Response.makeErrRsp("登录失效");
            }
            return Response.makeOKRsp(cacheUser.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp("获取登录信息异常:" + e.getMessage());
        }
    }


    @PostMapping("updatePassWord")
    public ResponseResult<String> updatePassWord(@RequestBody CommentUserBean commentUserBean) {
        try {
            if(ObjectUtil.isEmpty(commentUserBean)) {
                return Response.makeErrRsp("非法请求");
            }
            if(StrUtil.isBlank(commentUserBean.getUserEmail())) {
                return Response.makeErrRsp("请输入邮箱地址");
            }
            boolean exists = userInfoService.isExists(commentUserBean.getUserEmail(), null);
            if(!exists) {
                return Response.makeErrRsp("邮箱不存在，请重新注册");
            }
            if(StrUtil.isBlank(commentUserBean.getVerifyCode())) {
                return Response.makeErrRsp("请输入邮箱验证码");
            }
            if(StrUtil.isBlank(commentUserBean.getPassWord())) {
                return Response.makeErrRsp("请输入密码");
            }
            String cacheVerCode =  cacheService.getCacheInfoByCode(SysConstant.MAIL_CODE_CACHE + commentUserBean.getUserEmail() + commentUserBean.getVerifyCode());
            if(StrUtil.isBlank(cacheVerCode)) {
                return Response.makeErrRsp("邮箱验证码输入错误或已过期");
            }
            if(!StrUtil.equalsAnyIgnoreCase(commentUserBean.getVerifyCode(), cacheVerCode)) {
                return Response.makeErrRsp("请输入正确的邮箱验证码");
            }

            userInfoService.updatePassWord(commentUserBean.getUserEmail(),commentUserBean.getPassWord());
            return Response.makeRsp(ResultCode.SUCCESS.code,"密码修改成功，请重新登录");
        } catch (Exception e) {
            e.printStackTrace();
            return Response.makeErrRsp();
        }
    }


}
